package com.ruoyi.system.service.impl;

import com.ruoyi.common.enums.RoleEnum;
import com.ruoyi.common.enums.TeamTypeEnum;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.DefCompany;
import com.ruoyi.system.domain.DefDrill;
import com.ruoyi.system.domain.DefTeam;
import com.ruoyi.system.domain.DefTeamMember;
import com.ruoyi.system.domain.dto.TeamStatisticsDTO;
import com.ruoyi.system.domain.vo.PartakeTeamVO;
import com.ruoyi.system.domain.vo.TeamMemberCount;
import com.ruoyi.system.domain.vo.TeamStatisticsVO;
import com.ruoyi.system.mapper.DefCompanyMapper;
import com.ruoyi.system.mapper.DefDrillMapper;
import com.ruoyi.system.mapper.DefTeamMapper;
import com.ruoyi.system.mapper.DefTeamMemberMapper;
import com.ruoyi.system.service.IDefTeamService;

import java.util.*;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * 队伍管理Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-10-09
 */
@Service
public class DefTeamServiceImpl implements IDefTeamService 
{
    @Autowired
    private DefTeamMapper defTeamMapper;

    @Autowired
    private DefTeamMemberMapper defTeamMemberMapper;

    @Autowired
    private DefDrillMapper defDrillMapper;

    @Autowired
    private DefCompanyMapper defCompanyMapper;

    /**
     * 查询队伍管理
     * 
     * @param teamId 队伍管理主键
     * @return 队伍管理
     */
    @Override
    public DefTeam selectDefTeamByTeamId(Integer teamId)
    {
        return defTeamMapper.selectDefTeamByTeamId(teamId);
    }

    /**
     * 查询队伍管理列表
     * 
     * @param defTeam 队伍管理
     * @return 队伍管理
     */
    @Override
    public List<DefTeam> selectDefTeamList(DefTeam defTeam)
    {
        Integer drillId = SecurityUtils.getLoginUser().getDrillId();
        defTeam.setDrillId(drillId);
        List<DefTeam> defTeams = defTeamMapper.selectDefTeamList(defTeam);
        if (!CollectionUtils.isEmpty(defTeams)) {
            // 提取所有 teamId
            List<Integer> teamIds = defTeams.stream()
                    .map(DefTeam::getTeamId)
                    .collect(Collectors.toList());

            // 根据 teamIds 统计每个队伍的成员人数
            List<TeamMemberCount> teamMemberCountsList = defTeamMapper.getTeamUsersByTeamIds(teamIds);
            // 根据 team_id 聚合 team_user 列表
            Map<Integer, List<Integer>> teamUsersMap = teamMemberCountsList.stream()
                    .collect(Collectors.groupingBy(
                            TeamMemberCount::getTeamId,  // 按 teamId 分组
                            Collectors.mapping(TeamMemberCount::getTeamUser, Collectors.toList()) // 获取 teamUser 列表
                    ));


            // 将统计的成员人数填充回 defTeams
            defTeams.forEach(team -> {
                List<Integer> teamUsers = teamUsersMap.getOrDefault(team.getTeamId(), Collections.emptyList());
                team.setTeamUserCount(teamUsers.size());

                String teamUsersStr = teamUsers.stream()
                        .map(String::valueOf) // 将 Integer 转为 String
                        .collect(Collectors.joining(","));

                // 设置队伍的成员字符串
                team.setTeamUsers(teamUsersStr);


                // 解析 teamCompany，获取单位ID并转为公司名称
                String teamCompany = team.getTeamCompany();
                if ("0".equals(teamCompany)) {
                    // 如果为0，表示全部单位
                    team.setTeamCompanyDisplay("全部单位");
                } else if (StringUtils.isNotBlank(teamCompany)) {
                    // 将单位ID（1,2,3）转为 List<Integer>
//                    List<Integer> companyIds = Arrays.stream(teamCompany.split(","))
//                            .map(Integer::valueOf)
//                            .collect(Collectors.toList());
//
//                    // 根据单位ID查询公司名称
//                    List<DefCompany> companies = defCompanyMapper.selectCompanyNamesByIds(companyIds);
//                    List<String> companyNames = companies.stream()
//                            .map(DefCompany::getCompanyName)
//                            .collect(Collectors.toList());
//
//                    // 将公司名称重新拼接成字符串
//                    String companyNamesStr = String.join(",", companyNames);
//                    team.setTeamCompany(companyNamesStr);

                    team.setTeamCompanyDisplay("特定单位");
                }
            });
        }

        return defTeams;
    }

    /**
     * 新增队伍管理
     * 
     * @param defTeam 队伍管理
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertDefTeam(DefTeam defTeam)
    {
        Integer drillId = SecurityUtils.getLoginUser().getDrillId();
        DefDrill defDrill = defDrillMapper.selectDefDrillByDrillId(drillId);
        if (defDrill == null || defDrill.getInitScore() == null) {
            throw new RuntimeException("没有找到对应的演练");
        }
        if (TeamTypeEnum.DEFENSE.getDescription().equals(defTeam.getTeamType())) {
            defTeam.setScore(defDrill.getInitScore());
        }
        defTeam.setTeamCompany(defTeam.getTeamCompany());
        defTeam.setCreateTime(DateUtils.getNowDate());
        defTeam.setDrillId(drillId);
        int teamId = defTeamMapper.insertDefTeam(defTeam);
        DefTeamMember defTeamMember = new DefTeamMember();
        defTeamMember.setTeamId(teamId);
        defTeamMember.setDrillId(drillId);
        if (StringUtils.isNotBlank(defTeam.getTeamUsers())){
            String[] split = defTeam.getTeamUsers().split(",");
            for (String userId : split) {
                defTeamMember.setTeamUser(Integer.valueOf(userId));
                defTeamMember.setRoleId((long) RoleEnum.TEAM_MEMBER.getCode());
                defTeamMemberMapper.insertDefTeamMember(defTeamMember);
            }
        }
        return teamId;
    }

    /**
     * 修改队伍管理
     * 
     * @param defTeam 队伍管理
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateDefTeam(DefTeam defTeam)
    {
        Integer drillId = SecurityUtils.getLoginUser().getDrillId();
        defTeam.setUpdateTime(DateUtils.getNowDate());
        int res = defTeamMapper.updateDefTeam(defTeam);
        defTeamMemberMapper.deleteDefTeamMemberByTeamId(defTeam.getTeamId());

        String[] split = defTeam.getTeamUsers().split(",");
        DefTeamMember defTeamMember = new DefTeamMember();
        defTeamMember.setTeamId(defTeam.getTeamId());
        defTeamMember.setDrillId(drillId);
        for (String userId : split) {
            defTeamMember.setTeamUser(Integer.valueOf(userId));
            defTeamMember.setRoleId((long) RoleEnum.TEAM_MEMBER.getCode());
            defTeamMemberMapper.insertDefTeamMember(defTeamMember);
        }
        return res;
    }

    /**
     * 批量删除队伍管理
     * 
     * @param teamIds 需要删除的队伍管理主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteDefTeamByTeamIds(Integer[] teamIds)
    {
        int res = defTeamMapper.deleteDefTeamByTeamIds(teamIds);
        defTeamMemberMapper.deleteDefTeamMemberByTeamIds(teamIds);
        return res;
    }

    /**
     * 删除队伍管理信息
     * 
     * @param teamId 队伍管理主键
     * @return 结果
     */
    @Override
    public int deleteDefTeamByTeamId(Integer teamId)
    {
        int i = defTeamMapper.deleteDefTeamByTeamId(teamId);
        defTeamMemberMapper.deleteDefTeamMemberByTeamId(teamId);
        return i;
    }

    @Override
    public TeamStatisticsVO teamStatistics(TeamStatisticsDTO dto) {
        Integer drillId = SecurityUtils.getLoginUser().getDrillId();
        dto.setDrillId(drillId);
        TeamStatisticsVO vo = defTeamMapper.teamStatistics(dto);
        return vo;
    }

    @Override
    public PartakeTeamVO viewPartakeCount(Integer drillId) {
        Assert.notNull(drillId, "请传入drillId");
        int attackTeam = defTeamMapper.countTeamByType(drillId, "攻击方");
        int defendTeam = defTeamMapper.countTeamByType(drillId, "防守方");
        int attackUser = defTeamMapper.countTeamUserByType(drillId, "攻击方");
        int defendUser = defTeamMapper.countTeamUserByType(drillId, "攻击方");
        int referee = defTeamMapper.countRefByDrillId(drillId);
        PartakeTeamVO vo = new PartakeTeamVO();
        vo.setAttackTeamCount(attackTeam);
        vo.setDefendTeamCount(defendTeam);
        vo.setAttackUserCount(attackUser);
        vo.setDefendUserCount(defendUser);
        vo.setRefereeCount(referee);
        String companyIds = defTeamMapper.getCompanyByDrillId(drillId);
        if (StringUtils.isNotBlank(companyIds)) {
            String[] split = companyIds.split(",");
            long hasAll = Arrays.stream(split).filter(e -> "0".equals(e)).count();
            if (hasAll > 0) {
                int allCompany = defTeamMapper.countAllCompany();
                vo.setPartakeCompanyCount(allCompany);
            } else {
                long count = Arrays.stream(split).distinct().count();
                vo.setPartakeCompanyCount(Integer.valueOf(count + ""));
            }
        }
        return vo;
    }

    @Override
    public PartakeTeamVO getAllScore(Integer drillId) {
        Assert.notNull(drillId, "请传入drillId");
        return defTeamMapper.getAllScore(drillId);
    }

    @Override
    public List<PartakeTeamVO> getTimeScore(Integer drillId) {
        Assert.notNull(drillId, "请传入drillId");
        String[] timeRange = {"0","1","2","3","4","5"};
        List<String> rangeSet = Arrays.asList(timeRange);
        Set<String> collect = new HashSet<>();
        List<PartakeTeamVO> timeScore = defTeamMapper.getTimeScore(drillId);
        if (CollectionUtils.isNotEmpty(timeScore)) {
            collect = timeScore.stream().map(PartakeTeamVO::getTimeGroup).collect(Collectors.toSet());
        }
        for (String e : rangeSet) {
            if (!collect.contains(e)) {
                PartakeTeamVO vo = new PartakeTeamVO();
                vo.setTimeGroup(e);
                vo.setAttackAllScore(0);
                vo.setDefendAllScore(0);
                timeScore.add(vo);
            }
        }
        return timeScore;
    }
}
